#include "ipc.h"
#include <sys/socket.h>
#include <sys/un.h>
#include<errno.h>

int my_fd= -1;
int p_fd=-1;



int ipc_open(char* filepath,char* argv[]){

	if(my_fd==-1){
		struct sockaddr_un sockadd;
		sockadd.sun_family=AF_UNIX;
		sprintf(sockadd.sun_path,"/tmp/socket%d",getpid());

		my_fd=socket(AF_UNIX, SOCK_STREAM, 0);
		bind(my_fd, (struct sockaddr *)&sockadd, sizeof(sockadd));
		listen(my_fd,20);
	}

	int ret;
	switch(ret=fork()){
		case -1:
			printf("error2");
			exit(-21);
		case 0:
			close(my_fd);
			execve(filepath, argv,NULL);
		default:
			return ret;
	}
}


int ipc_msg_recive(int from, message_t* message){
	int fd=p_fd;
	if(from!=SERVER){

		fd=accept(my_fd, NULL, NULL);
	}

	if(fd==-1){
		return fd;
	}

	int msg_size;
	if(read(fd,(char*)&msg_size,sizeof(int))<=0) return -2;

	char * text=malloc(msg_size);//FREE
	if(read(fd,text,msg_size)<=0) return -2;

	message->size=msg_size;
	message->text=text;

	return from==SERVER? SERVER : fd;
}


int ipc_msg_send(int pid, message_t* message){
	
	int fd= pid;
	if(pid==SERVER){
		close(p_fd);
		p_fd=socket(AF_UNIX, SOCK_STREAM, 0);
		fd=p_fd;		

		struct sockaddr_un sockadd;
		sockadd.sun_family=AF_UNIX;
		sprintf(sockadd.sun_path,"/tmp/socket%d",getppid());	

		connect(fd, (struct sockaddr *)&sockadd, sizeof(sockadd));
	}
	
	char* plaintext=malloc(sizeof(int)+message->size);
	char* plaintextp=plaintext;

	*((int*)plaintextp)=message->size;
	plaintextp+=sizeof(int);

	memcpy(plaintextp,message->text,message->size);
	
	int writen=write(fd,plaintext,sizeof(int)+message->size);
	free(plaintext);
	
	if(pid!=SERVER){
		close(fd);
	}

	return -(writen<0);
}


void ipc_close(){
	if(my_fd!=-1){
		close(my_fd);
		char filepath[30];
		sprintf(filepath,"/tmp/socket%d",getpid());
		remove(filepath);
	}
}
